﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Pasta.Medio.Concrete;
using Pasta.Medio.Models;

// Scan location
// Relative path of file/folder processed
// Recordings found
//   Images
//   Videos
// New recordings
//   Images
//   Videos
// Progress
// Stop / Ok

namespace Pasta.Medio.Dialogs
{
	public partial class ScannerForm : DialogBase
	{
		MediaScanner _scanner;
		public SortableBindingList<MediaView> Media { get; private set; }
		private Results _results = new Results();
		private ScannerModel _model;

		public ScannerForm() : this(null)
		{
		}

		public ScannerForm( string path )
		{
			InitializeComponent();
			_model = new ScannerModel(path);
			_scanner = new MediaScanner(_model);
			_scanner.ProgressChanged += mediaWorker_ProgressChanged;
			Media = new SortableBindingList<MediaView>();
		}

		private void ScannerForm_Load(object sender, EventArgs e)
		{
			SetLabel(lblLocation, _model.Path);
			SetButton("Stop!", Properties.Resources.Stop_24);
			_scanner.Start();
		}

		private void SetButton(string text, Bitmap bitmap = null)
		{
			cancel.TextAlign = (bitmap == null) ? ContentAlignment.MiddleCenter : ContentAlignment.MiddleRight;
			cancel.Text = text;
			cancel.Image = bitmap;
		}

		private void mediaWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
		{
			ScannerModel model = e.UserState as ScannerModel;
			if (_scanner.State == Enums.WorkerState.Cancelled)
			{
				SetResult(Properties.Resources.FlagYellow_32, "Scanning recordings was stopped");
			}
			else if (_scanner.State == Enums.WorkerState.Error)
			{
				SetResult(Properties.Resources.FlagRed_32, "There was an error scanning the recordings");
			}
			else if (_scanner.State == Enums.WorkerState.Scanning)
			{
				if( e.ProgressPercentage < 0 )
				{
					progress.Style = ProgressBarStyle.Marquee;
				}
				else
				{
					SetLabel(lblFolder, model.CurrentFolder);
					SetLabel(lblRecordings, "{0}", model.NumFiles);
					SetLabel(lblImages, "{0}", model.ImageCount);
					SetLabel(lblVideos, "{0}", model.VideoCount);
				}
			}
			else if (_scanner.State == Enums.WorkerState.Analyzing)
			{
				if (e.ProgressPercentage < 0)
				{
					lblResult.Text = String.Format("{0:0.00} sec", _scanner.ElapsedTime / 1000F);
					progress.Style = ProgressBarStyle.Blocks;
				}
				else
				{
					SetLabel(lblFolder, model.CurrentFolder);
					SetLabel(lblRecording, model.CurrentFile);
					progress.Value = e.ProgressPercentage;
					SetLabel(lblProgress, "{0}%", e.ProgressPercentage);
					SetLabel(lblNew, "{0}", model.NewImages + model.NewVideos);
					SetLabel(lblNewImages, "{0}", model.NewImages);
					SetLabel(lblNewVideos, "{0}", model.NewVideos);

					if (_model.RunningSize > 0)
					{
						long remaining = _scanner.ElapsedTime * (_model.TotalSize - _model.RunningSize) / _model.RunningSize / 1000;
						long minutes = remaining / 60;
						long seconds = remaining % 60;
						if (remaining > 70)
							SetLabel(lblResult, "Analyzing recordings, {0} minutes remaining", minutes);
						else if (remaining > 50)
							SetLabel(lblResult, "Analyzing recordings, about 1 minute remaining", minutes);
						else if (remaining > 45)
							SetLabel(lblResult, "Analyzing recordings, less than 1 minute remaining", minutes);
						else
							SetLabel(lblResult, "Analyzing recordings, {0} seconds remaining", ((seconds + 4) / 5) * 5);
					}
				}
			}
			else if (_scanner.State == Enums.WorkerState.Complete)
			{
				SetResult(Properties.Resources.FlagGreen_32, "Scanning complete, {0} new recordings found.", lblNew.Text);
				Media = model.Media;
				SetButton("Close", Properties.Resources._903550_button_ok);
				//				mediaGrid.DataSource = _media;
				//! VIRTUAL MODE
				//mediaGrid.RowCount = _media.Count;
			}
		}

		private void SetResult(Bitmap bitmap, string txt, params object[] args)
		{
			throbber.Image = bitmap;
			SetLabel(lblResult, txt, args);
			progress.Value = 0;
		}

		private void SetLabel(Label label, string text, params object[] args)
		{
			string s = String.IsNullOrEmpty(text) ? "-" : String.Format(text, args);
			if (this.InvokeRequired)
			{
				Invoke((MethodInvoker)delegate
				{
					label.Text = s;
					Application.DoEvents();
				});
			}
			else
			{
				label.Text = s;
			}
		}

		private void buttonClick(object sender, EventArgs e)
		{
			if (_scanner.Cancel())
			{
				SetButton("Close");
			}
			else
			{
				DialogResult = DialogResult.OK;
				Close();
			}
		}
	}
}
